#include <stdio.h>
#include <string.h>
#include <inttypes.h> // 添加这个头文件以使用PRIu32宏
#include "esp_log.h"
#include "driver/sd_card.h"
#include "sd_test.h"

static const char *TAG = "sd_test";

/**
 * @brief 测试获取SD卡信息
 *
 * @param card SD卡信息
 * @return esp_err_t ESP_OK成功，其他值表示失败
 */
static esp_err_t test_sd_card_info(sdmmc_card_t *card)
{
    sd_card_info_t info;
    esp_err_t ret = sd_card_get_info(card, &info);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to get SD card info");
        return ret;
    }

    ESP_LOGI(TAG, "SD Card Information:");
    ESP_LOGI(TAG, "  Name: %s", info.name);
    ESP_LOGI(TAG, "  Type: %s", info.type);
    ESP_LOGI(TAG, "  Speed: %s", info.speed);
    ESP_LOGI(TAG, "  Size: %" PRIu64 " MB", info.size_mb);
    ESP_LOGI(TAG, "  CSD: ver=%d, sector_size=%d, capacity=%d, read_bl_len=%d", 
             info.csd.ver, info.csd.sector_size, info.csd.capacity, info.csd.read_bl_len);
    ESP_LOGI(TAG, "  SSR/EXT CSD: bus_width=%" PRIu32, info.ssr.bus_width);

    return ESP_OK;
}

// 写文件内容 path是路径 data是内容
static esp_err_t s_example_write_file(const char *path, char *data)
{
    ESP_LOGI(TAG, "Opening file %s", path);
    FILE *f = fopen(path, "w");   // 以只写方式打开路径中文件
    if (f == NULL) {
        ESP_LOGE(TAG, "Failed to open file for writing");
        return ESP_FAIL;
    }
    fprintf(f, data); // 写入内容
    fclose(f);  // 关闭文件
    ESP_LOGI(TAG, "File written");

    return ESP_OK;
}

// 读文件内容 path是路径
static esp_err_t s_example_read_file(const char *path)
{
    ESP_LOGI(TAG, "Reading file %s", path);
    FILE *f = fopen(path, "r");  // 以只读方式打开文件
    if (f == NULL) {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return ESP_FAIL;
    }
    char line[EXAMPLE_MAX_CHAR_SIZE];  // 定义一个字符串数组
    fgets(line, sizeof(line), f); // 获取文件中的内容到字符串数组
    fclose(f); // 关闭文件

    // strip newline
    char *pos = strchr(line, '\n'); // 查找字符串中的"\n"并返回其位置
    if (pos) {
        *pos = '\0'; // 把\n替换成\0
    }
    ESP_LOGI(TAG, "Read from file: '%s'", line); // 把数组内容输出到终端

    return ESP_OK;
}

/**
 * @brief 运行SD卡文件操作测试
 *
 * @param card SD卡信息
 * @return esp_err_t ESP_OK成功，其他值表示失败
 */
esp_err_t run_sd_card_test(sdmmc_card_t *card)
{
    esp_err_t ret;

    // 测试获取SD卡信息
    ret = test_sd_card_info(card);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "SD card info test failed");
        return ret;
    }

    // 新建一个txt文件 并且给文件中写入几个字符
    const char *file_hello = MOUNT_POINT"/你好hello.txt";
    char data[EXAMPLE_MAX_CHAR_SIZE];
    snprintf(data, EXAMPLE_MAX_CHAR_SIZE, "%s %s!\n", "你好hello先生", card->cid.name);
    ret = s_example_write_file(file_hello, data);
    if (ret != ESP_OK) {
        return ret;
    }

    // 打开txt文件，并读出文件中的内容
    ret = s_example_read_file(file_hello);
    if (ret != ESP_OK) {
        return ret;
    }

    return ESP_OK;
}